区块链网络的节点发现机制深入探讨
在startNode中,一旦本地主机创建完成,需要将其纳入到区块链网络(P2P网络),我们执行:
err = SetupDiscovery(ctx, host)
我们再次把此函数的的实现copy如下:
// SetupDiscovery 建立发现机制,并将本地主机连接到所有已经发现的对等端(peer)func SetupDiscovery(ctx context.Context, host host.Host) error {// 开启一个DHT,用于对等端(peer)发现。// 我们不仅仅是创建一个新的DHT,因为我们要求每一个端维护它自己的本地DHT副本,这样// 以来,DHT的引导节点可以关闭,不会影响后续的对等端发现kademliaDHT, err := dht.New(ctx, host)if err != nil {panic(err)}// 引导DHT。在缺省设置下,这生成一个后台线程,每5分钟刷新对等端表格log.Info("引导DHT")if err = kademliaDHT.Bootstrap(ctx); err != nil {panic(err)}// 让我们首先连接到所有的引导节点(bootstrap nodes),它们会告诉我们网络中的其他节点var wg sync.WaitGroupfor _, peerAddr := range dht.DefaultBootstrapPeers {peerinfo, _ := peer.AddrInfoFromP2pAddr(peerAddr)wg.Add(1)//使用多个协程,加快连接处理go func() {defer wg.Done()if err := host.Connect(ctx, *peerinfo); err != nil {log.Error(err)} else {log.Info("连接已建立,使用的引导节点是:", *peerinfo)}}()}wg.Wait()//阻塞,确保所有的协程全部返回// 我们使用一个会合点“wlsell.com”来宣布我们的位置// 这就像告诉你的朋友在某个具体的地点会合log.Info("宣布我们自己...")routingDiscovery := discovery.NewRoutingDiscovery(kademliaDHT)discovery.Advertise(ctx, routingDiscovery, "rendezvous:wlsell.com")log.Info("成功宣布!")// 现在,查找那些已经宣布的对等端// 这就像你的朋友告诉你会合的地点log.Info("搜索其它的对等端...")peerChan, err := routingDiscovery.FindPeers(ctx, "rendezvous:wlsell.com")if err != nil {panic(err)}// 连接到所有新发现的对等端(peer)for peer := range peerChan {if peer.ID == host.ID() {continue//不连接自己}log.Debug("找到对等端:", peer)log.Debug("正在连接到:", peer)err := host.Connect(context.Background(), peer)if err != nil {log.Warningf("连接到对等端 %s:失败 %s\\n", peer.ID.Pretty(), err)continue}log.Info("已经连接到:", peer)}return nil}
